/* Ingeniería - Crear componente patrón */

package edu.client;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.LayoutPanel;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;

import edu.client.IngenieriaService.IngenieriaService;
import edu.client.IngenieriaService.IngenieriaServiceAsync;
import edu.shared.DTO.ClaseEquipoPatronDTO;
import edu.shared.DTO.ComponentePatronDTO;
import edu.shared.DTO.EquipoPatronDTO;
import edu.shared.DTO.SubclaseEquipoPatronDTO;

public class P_CrearComponentePatron extends Composite {
	
	private String tituloTab;
	TabPanel padre;
	
	private ListBox claseCombo;
	private ListBox subclaseCombo;
	private ListBox planoCombo;
	private TextArea descripcionTecnicaTA;
	
	private Button crearComponenteBtn;
	
	private ListBox tipoCombo;
	private TextBox codigoComponenteTB;
	private TextBox nombreComponenteTB;
	private ListBox codigoComponenteCombo;
	private Label codigoSubcomponenteLabel;
	private TextBox codigoSubcomponenteTB;
	private Label nombreSubcomponenteLabel;
	private TextBox nombreSubcomponenteTB;
	
	private TextArea descripcionTecnicaDetallesTA;
	private TextBox puntoPedidoTB;
	private TextBox loteTB;
	
	private IngenieriaServiceAsync ingenieriaService;

	private List<EquipoPatronDTO> listaPlanos;
	private List<ComponentePatronDTO> listaComponentesPatron;
	
	public P_CrearComponentePatron(TabPanel padre, String titulo) {
		
		this.tituloTab = titulo;
		this.padre = padre;
		ingenieriaService = GWT.create(IngenieriaService.class);
		listaPlanos = new LinkedList<EquipoPatronDTO>();
	
		LayoutPanel layoutPanel = new LayoutPanel();
		initWidget(layoutPanel);
		layoutPanel.setSize((Window.getClientWidth() - 55) + "px", "800px");
		
		/// SECCIÓN EQUIPO
		
		Label equipoLabel = new Label("EQUIPO PATRÓN A UTILIZAR");
		equipoLabel.setStyleName("labelTitulo");
		layoutPanel.add(equipoLabel);
		layoutPanel.setWidgetLeftWidth(equipoLabel, 2.5, Unit.PCT, 95.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(equipoLabel, 15.0, Unit.PX, 50.0, Unit.PX);
		
		Label claseLabel = new Label("CLASE:");
		claseLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		claseLabel.setStyleName("gwt-LabelFormulario");
		layoutPanel.add(claseLabel);
		layoutPanel.setWidgetLeftWidth(claseLabel, 0.0, Unit.PCT, 17.3, Unit.PCT);
		layoutPanel.setWidgetTopHeight(claseLabel, 80.0, Unit.PX, 19.0, Unit.PX);
		
		// combo clases
		
		claseCombo = new ListBox();
		claseCombo.setEnabled(false);
		layoutPanel.add(claseCombo);
		layoutPanel.setWidgetLeftWidth(claseCombo, 17.5, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(claseCombo, 75.0, Unit.PX, 32.0, Unit.PX);
		
		claseCombo.addChangeHandler(new ChangeHandler() {

			@Override
			public void onChange(ChangeEvent event) {
				
				// si se selecciona la cadena vacía		
				if (claseCombo.getItemText(claseCombo.getSelectedIndex()).equals("")) {
					
					// limpiar y deshabilitar toda la pantalla
					subclaseCombo.setEnabled(false);					
					subclaseCombo.clear();
					planoCombo.setEnabled(false);
					planoCombo.clear();
					descripcionTecnicaTA.setText("");
					
					tipoCombo.setEnabled(false);
					tipoCombo.setItemSelected(0, true);
					codigoComponenteTB.setText("");
					nombreComponenteTB.setEnabled(false);
					nombreComponenteTB.setText("");
					
					codigoComponenteCombo.clear();
					codigoComponenteCombo.setVisible(false);
					codigoSubcomponenteLabel.setVisible(false);
					codigoSubcomponenteTB.setVisible(false);
					codigoSubcomponenteTB.setEnabled(false);
					codigoSubcomponenteTB.setText("");
					nombreSubcomponenteLabel.setVisible(false);
					nombreSubcomponenteTB.setVisible(false);
					nombreSubcomponenteTB.setEnabled(false);
					nombreSubcomponenteTB.setText("");
				}
				
				// si se selecciona una clase			
				else {
					cargarComboSubclases();
				}
			}
		});
		
		Label subclaseLabel = new Label("SUBCLASE: ");
		subclaseLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		subclaseLabel.setStyleName("gwt-LabelFormulario");
		layoutPanel.add(subclaseLabel);
		layoutPanel.setWidgetLeftWidth(subclaseLabel, 0.0, Unit.PCT, 17.3, Unit.PCT);
		layoutPanel.setWidgetTopHeight(subclaseLabel, 115.0, Unit.PX, 19.0, Unit.PX);
		
		// combo subclases
		
		subclaseCombo = new ListBox();
		subclaseCombo.setEnabled(false);
		layoutPanel.add(subclaseCombo);
		layoutPanel.setWidgetLeftWidth(subclaseCombo, 17.5, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(subclaseCombo, 110.0, Unit.PX, 32.0, Unit.PX);
		
		subclaseCombo.addChangeHandler(new ChangeHandler() {

			@Override
			public void onChange(ChangeEvent event) {
				
				// si se selecciona la cadena vacía		
				if (subclaseCombo.getItemText(subclaseCombo.getSelectedIndex()).equals("")) {
					
					// limpiar y deshabilitar toda la pantalla
					
					planoCombo.setEnabled(false);
					planoCombo.clear();
					descripcionTecnicaTA.setText("");
					
					tipoCombo.setEnabled(false);
					tipoCombo.setItemSelected(0, true);
					codigoComponenteTB.setText("");
					nombreComponenteTB.setEnabled(false);
					nombreComponenteTB.setText("");
					
					codigoComponenteCombo.clear();
					codigoComponenteCombo.setVisible(false);
					codigoSubcomponenteLabel.setVisible(false);
					codigoSubcomponenteTB.setVisible(false);
					codigoSubcomponenteTB.setEnabled(false);
					codigoSubcomponenteTB.setText("");
					nombreSubcomponenteLabel.setVisible(false);
					nombreSubcomponenteTB.setVisible(false);
					nombreSubcomponenteTB.setEnabled(false);
					nombreSubcomponenteTB.setText("");
				}
				
				// si se selecciona una subclase			
				else {
					cargarComboPlanos();
				}
			}
		});
		
		Label planoLabel = new Label("PLANO: ");
		planoLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		planoLabel.setStyleName("gwt-LabelFormulario");
		layoutPanel.add(planoLabel);
		layoutPanel.setWidgetLeftWidth(planoLabel, 50.0, Unit.PCT, 19.8, Unit.PCT);
		layoutPanel.setWidgetTopHeight(planoLabel, 115.0, Unit.PX, 19.0, Unit.PX);
		
		// combo planos
		
		planoCombo = new ListBox();
		planoCombo.setEnabled(false);
		layoutPanel.add(planoCombo);
		layoutPanel.setWidgetLeftWidth(planoCombo, 70.0, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(planoCombo, 110.0, Unit.PX, 32.0, Unit.PX);
		
		planoCombo.addChangeHandler(new ChangeHandler() {

			@Override
			public void onChange(ChangeEvent event) {
				
				// si se selecciona la cadena vacía		
				if (planoCombo.getItemText(planoCombo.getSelectedIndex()).equals("")) {
					
					// limpiar y deshabilitar toda la pantalla
					
					descripcionTecnicaTA.setText("");
					
					tipoCombo.setEnabled(false);
					tipoCombo.setItemSelected(0, true);
					codigoComponenteTB.setText("");
					nombreComponenteTB.setEnabled(false);
					nombreComponenteTB.setText("");
					
					codigoComponenteCombo.clear();
					codigoComponenteCombo.setVisible(false);
					codigoSubcomponenteLabel.setVisible(false);
					codigoSubcomponenteTB.setVisible(false);
					codigoSubcomponenteTB.setEnabled(false);
					codigoSubcomponenteTB.setText("");
					nombreSubcomponenteLabel.setVisible(false);
					nombreSubcomponenteTB.setVisible(false);
					nombreSubcomponenteTB.setEnabled(false);
					nombreSubcomponenteTB.setText("");
				}
				
				// si se selecciona una subclase			
				else {
					cargarDatosEquipo();
				}
			}
		});
			
		Label descripcionTecnicaLabel = new Label("DESCRIPCIÓN TÉCNICA:");
		descripcionTecnicaLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		descripcionTecnicaLabel.setStyleName("gwt-LabelFormulario");
		layoutPanel.add(descripcionTecnicaLabel);
		layoutPanel.setWidgetLeftWidth(descripcionTecnicaLabel, 0.0, Unit.PCT, 17.3, Unit.PCT);
		layoutPanel.setWidgetTopHeight(descripcionTecnicaLabel, 185.0, Unit.PX, 19.0, Unit.PX);
		
		descripcionTecnicaTA = new TextArea();
		layoutPanel.add(descripcionTecnicaTA);
		layoutPanel.setWidgetLeftWidth(descripcionTecnicaTA, 17.5, Unit.PCT, 77.5, Unit.PCT);
		layoutPanel.setWidgetTopHeight(descripcionTecnicaTA, 145.0, Unit.PX, 100.0, Unit.PX);
		descripcionTecnicaTA.setEnabled(false);
		
		///
		
		/// SECCIÓN COMPONENTE		
		
		Label componenteLabel = new Label("COMPONENTE PATRÓN");
		componenteLabel.setStyleName("labelTitulo");
		layoutPanel.add(componenteLabel);
		layoutPanel.setWidgetLeftWidth(componenteLabel, 2.5, Unit.PCT, 95.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(componenteLabel, 240.0, Unit.PX, 50.0, Unit.PX);
		
		Label tipoLabel = new Label("TIPO:");
		tipoLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		tipoLabel.setStyleName("gwt-LabelFormulario");
		layoutPanel.add(tipoLabel);
		layoutPanel.setWidgetLeftWidth(tipoLabel, 4.0, Unit.PCT, 13.2, Unit.PCT);
		layoutPanel.setWidgetTopHeight(tipoLabel, 305.0, Unit.PX, 19.0, Unit.PX);
		
		tipoCombo = new ListBox();
		layoutPanel.add(tipoCombo);
		layoutPanel.setWidgetLeftWidth(tipoCombo, 17.5, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(tipoCombo, 300.0, Unit.PX, 32.0, Unit.PX);
		
		tipoCombo.addItem("COMPONENTE");
		tipoCombo.addItem("SUBCOMPONENTE");
		
		tipoCombo.setEnabled(false);
		
		//Si se cambia el tipo seleccionado, se modifican los campos mostrados.
		tipoCombo.addChangeHandler(new ChangeHandler() {
			public void onChange(ChangeEvent event) {
				if(tipoCombo.getItemText(tipoCombo.getSelectedIndex()).equals("COMPONENTE")) {
					
					codigoComponenteCombo.setVisible(false);
					nombreComponenteTB.setEnabled(true);
					nombreComponenteTB.setText("");
					codigoSubcomponenteLabel.setVisible(false);
					codigoSubcomponenteTB.setVisible(false);
					codigoSubcomponenteTB.setEnabled(false);
					codigoSubcomponenteTB.setText("");
					nombreSubcomponenteLabel.setVisible(false);
					nombreSubcomponenteTB.setVisible(false);
					nombreSubcomponenteTB.setEnabled(false);
					nombreSubcomponenteTB.setText("");
											
				}
				else {
					// si no existen componentes cargados para el equipo seleccionado, no se permite crear un subcomponente
					if (codigoComponenteCombo.getItemCount() == 1) {
						Window.alert("No existen componentes para el equipo seleccionado.");
						nombreComponenteTB.setText("");
						tipoCombo.setSelectedIndex(0);
					}
					
					// si existen componentes cargados para el equipo seleccionado, se permite crear un subcomponente
					else {
						nombreComponenteTB.setEnabled(false);
						
						codigoComponenteCombo.setVisible(true);
						codigoComponenteCombo.setEnabled(true);
						codigoSubcomponenteLabel.setVisible(true);
						codigoSubcomponenteTB.setVisible(true);
						nombreSubcomponenteLabel.setVisible(true);
						nombreSubcomponenteTB.setVisible(true);
						nombreSubcomponenteTB.setEnabled(true);
						nombreSubcomponenteTB.setText("");
					}					
				}
			}
		});
		
		AbsolutePanel componenteOSubcomponenteAP = new AbsolutePanel();
		componenteOSubcomponenteAP.setStyleName("panelConBorde");
		layoutPanel.add(componenteOSubcomponenteAP);
		layoutPanel.setWidgetLeftWidth(componenteOSubcomponenteAP, 1.0, Unit.PCT, 95.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(componenteOSubcomponenteAP, 337.0, Unit.PX, 95.0, Unit.PX);
		
		Label codigoComponenteLabel = new Label("CÓDIGO DE COMPONENTE:");
		codigoComponenteLabel.setStyleName("gwt-LabelFormulario");
		codigoComponenteLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		layoutPanel.add(codigoComponenteLabel);
		layoutPanel.setWidgetLeftWidth(codigoComponenteLabel, 0.0, Unit.PCT, 17.3, Unit.PCT);
		layoutPanel.setWidgetTopHeight(codigoComponenteLabel, 355.0, Unit.PX, 19.0, Unit.PX);
		
		codigoComponenteTB = new TextBox();
		layoutPanel.add(codigoComponenteTB);
		layoutPanel.setWidgetLeftWidth(codigoComponenteTB, 17.5, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(codigoComponenteTB, 350.0, Unit.PX, 32.0, Unit.PX);
		
		Label nombreComponenteLabel = new Label("NOMBRE DE COMPONENTE:");
		nombreComponenteLabel.setStyleName("gwt-LabelFormulario");
		nombreComponenteLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		layoutPanel.add(nombreComponenteLabel);
		layoutPanel.setWidgetLeftWidth(nombreComponenteLabel, 50.0, Unit.PCT, 19.8, Unit.PCT);
		layoutPanel.setWidgetTopHeight(nombreComponenteLabel, 355.0, Unit.PX, 19.0, Unit.PX);
		
		nombreComponenteTB = new TextBox();
		layoutPanel.add(nombreComponenteTB);
		layoutPanel.setWidgetLeftWidth(nombreComponenteTB, 70.0, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(nombreComponenteTB, 350.0, Unit.PX, 32.0, Unit.PX);
		
		codigoComponenteCombo = new ListBox();
		layoutPanel.add(codigoComponenteCombo);
		layoutPanel.setWidgetLeftWidth(codigoComponenteCombo, 17.5, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(codigoComponenteCombo, 350.0, Unit.PX, 32.0, Unit.PX);
		
		codigoComponenteCombo.addChangeHandler(new ChangeHandler() {

			@Override
			public void onChange(ChangeEvent event) {
				
				// si se selecciona la cadena vacía		
				if (codigoComponenteCombo.getItemText(codigoComponenteCombo.getSelectedIndex()).equals("")) {
					
					// limpiar y deshabilitar toda la pantalla
					nombreSubcomponenteTB.setEnabled(false);
					codigoSubcomponenteTB.setText("");
					nombreSubcomponenteTB.setText("");
					nombreComponenteTB.setText("");
				}
				
				// si se selecciona un componente			
				else {
							
					String sgteCodigoSubcomponente = calcularSgteCodigoSubcomponente();
					
					codigoSubcomponenteTB.setText(sgteCodigoSubcomponente);
					nombreSubcomponenteTB.setText("");
					nombreSubcomponenteTB.setEnabled(true);
					
					int componenteSeleccionado = codigoComponenteCombo.getSelectedIndex();
					int i = 0;
					int j = 0;
					
					//Se busca el componente seleccionado, siempre que no sea un subcomponente.
					while (j != componenteSeleccionado) {
						if(listaComponentesPatron.get(i).getCodigoSubcomponente() == 0)
							j++;
						if(j != componenteSeleccionado)
							i++;
					}
					
					nombreComponenteTB.setText(listaComponentesPatron.get(i).getNombre());
				}
			}
		});
		
		
		codigoSubcomponenteLabel = new Label("CÓDIGO DE SUBCOMPONENTE: ");
		codigoSubcomponenteLabel.setStyleName("gwt-LabelFormulario");
		codigoSubcomponenteLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		layoutPanel.add(codigoSubcomponenteLabel);
		layoutPanel.setWidgetLeftWidth(codigoSubcomponenteLabel, 0.0, Unit.PCT, 17.3, Unit.PCT);
		layoutPanel.setWidgetTopHeight(codigoSubcomponenteLabel, 390.0, Unit.PX, 19.0, Unit.PX);
		
		codigoSubcomponenteTB = new TextBox();
		layoutPanel.add(codigoSubcomponenteTB);
		layoutPanel.setWidgetLeftWidth(codigoSubcomponenteTB, 17.5, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(codigoSubcomponenteTB, 385.0, Unit.PX, 32.0, Unit.PX);
		
		nombreSubcomponenteLabel = new Label("NOMBRE DE SUBCOMPONENTE: ");
		nombreSubcomponenteLabel.setStyleName("gwt-LabelFormulario");
		nombreSubcomponenteLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		layoutPanel.add(nombreSubcomponenteLabel);
		layoutPanel.setWidgetLeftWidth(nombreSubcomponenteLabel, 50.0, Unit.PCT, 19.8, Unit.PCT);
		layoutPanel.setWidgetTopHeight(nombreSubcomponenteLabel, 390.0, Unit.PX, 19.0, Unit.PX);
		
		nombreSubcomponenteTB = new TextBox();
		layoutPanel.add(nombreSubcomponenteTB);
		layoutPanel.setWidgetLeftWidth(nombreSubcomponenteTB, 70.0, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(nombreSubcomponenteTB, 385.0, Unit.PX, 32.0, Unit.PX);
		
		codigoComponenteTB.setEnabled(false);
		nombreComponenteTB.setEnabled(false);
		codigoComponenteCombo.setVisible(false);
		codigoSubcomponenteLabel.setVisible(false);
		codigoSubcomponenteTB.setVisible(false);
		nombreSubcomponenteLabel.setVisible(false);
		nombreSubcomponenteTB.setVisible(false);

		///
		
		/// SECCIÓN DETALLES

		Label detallesLabel = new Label("DETALLES DEL COMPONENTE PATRÓN");
		detallesLabel.setStyleName("labelTitulo");
		layoutPanel.add(detallesLabel);
		layoutPanel.setWidgetLeftWidth(detallesLabel, 2.5, Unit.PCT, 95.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(detallesLabel, 442.0, Unit.PX, 50.0, Unit.PX);
		
		Label planoDetallesLabel = new Label("PLANO:");
		planoDetallesLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		planoDetallesLabel.setStyleName("gwt-LabelFormulario");
		layoutPanel.add(planoDetallesLabel);
		layoutPanel.setWidgetLeftWidth(planoDetallesLabel, 0.0, Unit.PCT, 17.3, Unit.PCT);
		layoutPanel.setWidgetTopHeight(planoDetallesLabel, 505.0, Unit.PX, 19.0, Unit.PX);
		
		TextBox planoTB = new TextBox();
		planoTB.setEnabled(false);
		planoTB.setText("00");
		layoutPanel.add(planoTB);
		layoutPanel.setWidgetLeftWidth(planoTB, 17.5, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(planoTB, 500.0, Unit.PX, 32.0, Unit.PX);
		
		Label versionLabel = new Label("VERSIÓN:");
		versionLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		versionLabel.setStyleName("gwt-LabelFormulario");
		layoutPanel.add(versionLabel);
		layoutPanel.setWidgetLeftWidth(versionLabel, 50.0, Unit.PCT, 19.8, Unit.PCT);
		layoutPanel.setWidgetTopHeight(versionLabel, 505.0, Unit.PX, 19.0, Unit.PX);
		
		TextBox versionTB = new TextBox();
		versionTB.setEnabled(false);
		versionTB.setText("M0");
		layoutPanel.add(versionTB);
		layoutPanel.setWidgetLeftWidth(versionTB, 70.0, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(versionTB, 500.0, Unit.PX, 32.0, Unit.PX);
		
		Label descripcionTecnicaDetallesLabel = new Label("DESCRIPCIÓN TÉCNICA:");
		descripcionTecnicaDetallesLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		descripcionTecnicaDetallesLabel.setStyleName("gwt-LabelFormulario");
		layoutPanel.add(descripcionTecnicaDetallesLabel);
		layoutPanel.setWidgetLeftWidth(descripcionTecnicaDetallesLabel, 0.0, Unit.PCT, 17.3, Unit.PCT);
		layoutPanel.setWidgetTopHeight(descripcionTecnicaDetallesLabel, 580.0, Unit.PX, 19.0, Unit.PX);
		
		descripcionTecnicaDetallesTA = new TextArea();
		layoutPanel.add(descripcionTecnicaDetallesTA);
		layoutPanel.setWidgetLeftWidth(descripcionTecnicaDetallesTA, 17.5, Unit.PCT, 77.5, Unit.PCT);
		layoutPanel.setWidgetTopHeight(descripcionTecnicaDetallesTA, 540.0, Unit.PX, 100.0, Unit.PX);
		
		Label puntoPedidoLabel = new Label("PUNTO DE PEDIDO:");
		puntoPedidoLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		puntoPedidoLabel.setStyleName("gwt-LabelFormulario");
		layoutPanel.add(puntoPedidoLabel);
		layoutPanel.setWidgetLeftWidth(puntoPedidoLabel, 0.0, Unit.PCT, 17.3, Unit.PCT);
		layoutPanel.setWidgetTopHeight(puntoPedidoLabel, 665.0, Unit.PX, 19.0, Unit.PX);
		
		puntoPedidoTB = new TextBox();
		layoutPanel.add(puntoPedidoTB);
		layoutPanel.setWidgetLeftWidth(puntoPedidoTB, 17.5, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(puntoPedidoTB, 660.0, Unit.PX, 32.0, Unit.PX);
		
		Label loteLabel = new Label("LOTE:");
		loteLabel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		loteLabel.setStyleName("gwt-LabelFormulario");
		layoutPanel.add(loteLabel);
		layoutPanel.setWidgetLeftWidth(loteLabel, 50.0, Unit.PCT, 19.8, Unit.PCT);
		layoutPanel.setWidgetTopHeight(loteLabel, 665.0, Unit.PX, 19.0, Unit.PX);
		
		loteTB = new TextBox();
		layoutPanel.add(loteTB);
		layoutPanel.setWidgetLeftWidth(loteTB, 70.0, Unit.PCT, 25.0, Unit.PCT);
		layoutPanel.setWidgetTopHeight(loteTB, 660.0, Unit.PX, 32.0, Unit.PX);
		
		///
		
		/// SECCIÓN PIE
		
		///PIE
		
		Label pieLabel = new Label("");
		pieLabel.setStyleName("labelTitulo");
		layoutPanel.add(pieLabel);
		layoutPanel.setWidgetLeftWidth(pieLabel, 2.5, Unit.PCT, 95.0, Unit.PCT);
		layoutPanel.setWidgetBottomHeight(pieLabel, 70.0, Unit.PX, 50.0, Unit.PX);
	
		// botón CREAR COMPONENTE PATRÓN
		
		crearComponenteBtn = new Button("CREAR");
		layoutPanel.add(crearComponenteBtn);
		layoutPanel.setWidgetRightWidth(crearComponenteBtn, 17.5, Unit.PCT, 10.0, Unit.PCT);
		layoutPanel.setWidgetBottomHeight(crearComponenteBtn, 15.0, Unit.PX, 28.0, Unit.PX);
		
		// al hacer clic sobre el botón CREAR COMPONENTE PATRÓN
		crearComponenteBtn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				
				crearComponenteBtn.setEnabled(false);
				
				List<String> errores = new LinkedList<String>();
				String mensaje = "";
				
				errores = validarDatos();
				
				// si hubo errores, se arma el mensaje y se alerta al usuario.
				if(errores.size() > 0) {
					
					mensaje = mensaje + errores.get(0);
					
					for(int i=1; i<errores.size(); i++) {
						mensaje = mensaje + '\n' + '\n' + errores.get(i);
					}
					
					Window.alert(mensaje);
					crearComponenteBtn.setEnabled(true);
				}
				
				// si no hubo ningún error, se procede a registrar el componente o subcomponente.
				else {								
					registrarComponentePatron();
				}
			}
		});
		
		// botón CANCELAR
		
		Button cancelarBtn = new Button("CANCELAR");
		layoutPanel.add(cancelarBtn);
		layoutPanel.setWidgetRightWidth(cancelarBtn, 5.0, Unit.PCT, 10.0, Unit.PCT);
		layoutPanel.setWidgetBottomHeight(cancelarBtn, 15.0, Unit.PX, 28.0, Unit.PX);
		
		cancelarBtn.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				salir();
			}
		});
		
		///	
		
		/// CARGA DE PANTALLA
		
		// se carga el combo de clases
		cargarComboClases();
		
		///
	}

	/** 
	 * Método que carga la lista desplegable de clases de equipo patrón.
	 */
	private void cargarComboClases() {
	
		ingenieriaService.buscarClasesEquipoPatron(new AsyncCallback<List<ClaseEquipoPatronDTO>>() {
			
			@Override
			public void onSuccess(List<ClaseEquipoPatronDTO> listaClasesEquipoPatronDTO) {

				// si aún no se cargó ningún equipo patrón
				if (listaClasesEquipoPatronDTO.isEmpty()) {
					Window.alert("No se pueden crear componentes: aún no se ha cargado ningún equipo patrón.");
					crearComponenteBtn.setEnabled(false);
				}
				
				else {
										
					// se agrega como primer elemento a la cadena vacía, para no realizar una carga forzada inicial
					claseCombo.addItem("");
					
					for(ClaseEquipoPatronDTO claseEquipoPatronDTO: listaClasesEquipoPatronDTO) {
						
						// cada ítem de la lista está representado como: código de clase - nombre de clase
						claseCombo.addItem(Validaciones.rellenarCodigo(claseEquipoPatronDTO.getCodigoClaseEquipoPatron()) + " - " + claseEquipoPatronDTO.getNombre());	
					}
					
					// se habilita el combo de clases
					claseCombo.setEnabled(true);
				}		
			}

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("ERROR EN EL SERVICIO");
			}
		});
	}
	
	/**
	 * Método que carga la lista desplegable de subclases
	 */
	private void cargarComboSubclases() {
		
		int codigoClase = Integer.valueOf(claseCombo.getItemText(claseCombo.getSelectedIndex()).split(" ")[0]);
		
		ingenieriaService.buscarSubclasesEquipoPatron(codigoClase, new AsyncCallback<List<SubclaseEquipoPatronDTO>>() {
			
			public void onSuccess(List<SubclaseEquipoPatronDTO> listaSubclasesEquipoPatronDTO) {
				
				// limpiar pantalla
				
				subclaseCombo.setEnabled(true);					
				subclaseCombo.clear();
				planoCombo.setEnabled(false);
				planoCombo.clear();
				descripcionTecnicaTA.setText("");
				
				tipoCombo.setEnabled(false);
				tipoCombo.setItemSelected(0, true);
				codigoComponenteTB.setText("");
				nombreComponenteTB.setEnabled(false);
				nombreComponenteTB.setText("");
				
				codigoComponenteCombo.clear();
				codigoComponenteCombo.setVisible(false);
				codigoSubcomponenteLabel.setVisible(false);
				codigoSubcomponenteTB.setVisible(false);
				codigoSubcomponenteTB.setEnabled(false);
				codigoSubcomponenteTB.setText("");
				nombreSubcomponenteLabel.setVisible(false);
				nombreSubcomponenteTB.setVisible(false);
				nombreSubcomponenteTB.setEnabled(false);
				nombreSubcomponenteTB.setText("");
					
				// se agrega como primer elemento a la cadena vacía, para no realizar una carga forzada inicial
				subclaseCombo.addItem("");
				
				for(SubclaseEquipoPatronDTO subclase: listaSubclasesEquipoPatronDTO) {
								
					// cada ítem de la lista está representado como: código de subclase - nombre de subclase
					subclaseCombo.addItem(Validaciones.rellenarCodigo(subclase.getCodigoSubclase()) + " - " + subclase.getNombre());	
				}
			}

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("ERROR EN EL SERVICIO");
			}	
		});	
	}
	
	/**
	 * Método que carga la lista desplegable de planos
	 */
	private void cargarComboPlanos() {
		
		int codigoClase = Integer.valueOf(claseCombo.getItemText(claseCombo.getSelectedIndex()).split(" ")[0]);
		int codigoSubclase = Integer.valueOf(subclaseCombo.getItemText(subclaseCombo.getSelectedIndex()).split(" ")[0]);
		
		// se buscan los equipos patrón con la clase y subclase especificadas
		ingenieriaService.buscarEquiposPatronUltimaVersion(codigoClase, codigoSubclase, new AsyncCallback<List<EquipoPatronDTO>>() {
			
			public void onSuccess(List<EquipoPatronDTO> listaEquiposPatron) {
				
				listaPlanos = listaEquiposPatron;
				
				// limpiar pantalla
				
				planoCombo.setEnabled(true);
				planoCombo.clear();
				descripcionTecnicaTA.setText("");
				
				tipoCombo.setEnabled(false);
				tipoCombo.setItemSelected(0, true);
				codigoComponenteTB.setText("");
				nombreComponenteTB.setEnabled(false);
				nombreComponenteTB.setText("");
				
				codigoComponenteCombo.clear();
				codigoComponenteCombo.setVisible(false);
				codigoSubcomponenteLabel.setVisible(false);
				codigoSubcomponenteTB.setVisible(false);
				codigoSubcomponenteTB.setEnabled(false);
				codigoSubcomponenteTB.setText("");
				nombreSubcomponenteLabel.setVisible(false);
				nombreSubcomponenteTB.setVisible(false);
				nombreSubcomponenteTB.setEnabled(false);
				nombreSubcomponenteTB.setText("");
					
				// se agrega como primer elemento a la cadena vacía, para no realizar una carga forzada inicial
				planoCombo.addItem("");
				
				// se agregan los planos a la lista desplegable
				for(EquipoPatronDTO equipo: listaEquiposPatron) {
								
					planoCombo.addItem(Validaciones.rellenarCodigo(equipo.getPlano()));	
				}
			}

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("ERROR EN EL SERVICIO");
			}	
		});	
	}
	
	/**
	 * Método que carga los datos del equipo seleccionado, y habilita las secciones de componente y subcomponente
	 */
	private void cargarDatosEquipo() {
		
		EquipoPatronDTO equipoSeleccionado = null;
		
		int plano = Integer.valueOf(planoCombo.getItemText(planoCombo.getSelectedIndex()));
		
		// se obtiene el equipo seleccionado
		for (EquipoPatronDTO e: listaPlanos) {
			
			if (e.getPlano() == plano) {
				equipoSeleccionado = e;
				break;
			}
		}
		
		// se carga la descripción técnica
		if (equipoSeleccionado.getDescripcionTecnica() == null) {
			descripcionTecnicaTA.setText("");
		}
		
		else {
			descripcionTecnicaTA.setText(equipoSeleccionado.getDescripcionTecnica());
		}
		
		tipoCombo.setEnabled(false);
		tipoCombo.setItemSelected(0, true);
		codigoComponenteTB.setText("");
		nombreComponenteTB.setText("");
		
		codigoComponenteCombo.clear();
		codigoComponenteCombo.setVisible(false);
		codigoSubcomponenteLabel.setVisible(false);
		codigoSubcomponenteTB.setVisible(false);
		codigoSubcomponenteTB.setEnabled(false);
		codigoSubcomponenteTB.setText("");
		nombreSubcomponenteLabel.setVisible(false);
		nombreSubcomponenteTB.setVisible(false);
		nombreSubcomponenteTB.setEnabled(false);
		nombreSubcomponenteTB.setText("");
		
		cargarPanelComponente();
		cargarPanelSubcomponente();
	}

	private void cargarPanelComponente() {
		
		int codigoClase = Integer.valueOf(claseCombo.getItemText(claseCombo.getSelectedIndex()).split(" ")[0]);
		int codigoSubclase = Integer.valueOf(subclaseCombo.getItemText(subclaseCombo.getSelectedIndex()).split(" ")[0]);
		
		// se buscan los componentes patrón para la clase y subclase especificadas
		ingenieriaService.buscarComponentesPatron(codigoClase, codigoSubclase, new AsyncCallback<List<ComponentePatronDTO>>() {

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("ERROR EN EL SERVICIO");				
			}

			@Override
			public void onSuccess(List<ComponentePatronDTO> listaComponentes) {
				
				// se actualiza la variable de componentes
				listaComponentesPatron = listaComponentes;
				
				String sgteCodigoComponente = calcularSgteCodigoComponente(listaComponentes);
				
				tipoCombo.setEnabled(true);
				tipoCombo.setItemSelected(0, true);
				codigoComponenteTB.setText(sgteCodigoComponente);
				nombreComponenteTB.setEnabled(true);							
			}
		});
	}

	private void cargarPanelSubcomponente() {
				
		int codigoClase = Integer.valueOf(claseCombo.getItemText(claseCombo.getSelectedIndex()).split(" ")[0]);
		int codigoSubclase = Integer.valueOf(subclaseCombo.getItemText(subclaseCombo.getSelectedIndex()).split(" ")[0]);
		
		// se buscan los componentes patrón para la clase y subclase especificadas
		ingenieriaService.buscarComponentesPatron(codigoClase, codigoSubclase, new AsyncCallback<List<ComponentePatronDTO>>() {
		
			@Override
			public void onFailure(Throwable caught) {
				Window.alert("ERROR EN EL SERVICIO");				
			}
			
			@Override
			public void onSuccess(List<ComponentePatronDTO> listaComponentes) {
				
				// se carga el combo de componentes
				codigoComponenteCombo.addItem("");
				
				for (ComponentePatronDTO c: listaComponentes) {
					
					// si es un componente, y no un subcomponente (cdo el código de subcomponente es 0, significa que se trata de un componente)
					if (c.getCodigoSubcomponente() == 0) {
						codigoComponenteCombo.addItem(Validaciones.rellenarCodigo(c.getCodigoComponente()));
					}
				}
			}
		});
	}	

	/**
	 * Método que calcula el siguiente número de componente (el primero disponible)
	 * @param listaComponentes
	 * @return el sgte número de componente
	 */
	private String calcularSgteCodigoComponente(List<ComponentePatronDTO> listaComponentes) {
		
		// se ordena ascendentemente la lista de componentes, por código de componente
		Collections.sort(listaComponentes);
		
		// se calcula el siguiente número de componente (se busca el primer hueco)
		
		int nroNuevoComponente = 1;
		boolean bandera = true;
		
		while(bandera) {
			
			int i = 0;
			
			boolean componenteFaltante = true;
			
			while (i < listaComponentes.size()) {
				
				//Cuando se encuentra el primer hueco libre, establece componente faltante a false.
				if (nroNuevoComponente == listaComponentes.get(i).getCodigoComponente()) {
					componenteFaltante = false;							
				}
				
				i++;
			}
			
			//Si no falta ese componente, se sigue con el próximo.
			if(!componenteFaltante)
				nroNuevoComponente++;
			else
				bandera = false;
		}

		return Validaciones.rellenarCodigo(nroNuevoComponente);
	}
	
	/**
	 * Método que calcula el siguiente número de subcomponente.
	 * @return el sgte número de subcomponente
	 */
	private String calcularSgteCodigoSubcomponente() {
		
		int componenteSeleccionado = Integer.valueOf(codigoComponenteCombo.getItemText(codigoComponenteCombo.getSelectedIndex()));
		
		int mayorCodigoSubcomponente = -1;
		
		for(ComponentePatronDTO c: listaComponentesPatron) {
			
			// si se trata del componente seleccionado, y, si su código de subcomponente es mayor q el actual
			if (c.getCodigoComponente() == componenteSeleccionado && c.getCodigoSubcomponente() > mayorCodigoSubcomponente) {
				mayorCodigoSubcomponente = c.getCodigoSubcomponente();
			}
		}
		
		return Validaciones.rellenarCodigo(mayorCodigoSubcomponente + 1);
	}
	
	/** Método que registra el componente o subcomponente patrón especificado en la pantalla.
	 * 
	 */
	private void registrarComponentePatron() {
		
		// se obtiene el equipo seleccionado
		
		EquipoPatronDTO equipoSeleccionado = null;
		int codigoClase = Integer.valueOf(claseCombo.getItemText(claseCombo.getSelectedIndex()).split(" ")[0]);
		int codigoSubclase = Integer.valueOf(subclaseCombo.getItemText(subclaseCombo.getSelectedIndex()).split(" ")[0]);
		int plano = Integer.valueOf(planoCombo.getItemText(planoCombo.getSelectedIndex()));
		
		for (EquipoPatronDTO e: listaPlanos) {
			
			if (e.getPlano() == plano) {
				equipoSeleccionado = e;
				break;
			}
		}
		
		// se crea la estrutucra del componente patrón DTO.
	
		ComponentePatronDTO componente = new ComponentePatronDTO();
		
		componente.setCodigoClase(codigoClase);
		
		componente.setCodigoSubclase(codigoSubclase);
			
		// si se ha especificado un componente
		if (tipoCombo.getItemText(tipoCombo.getSelectedIndex()).equals("COMPONENTE")) {
			
			componente.setCodigoComponente(Integer.valueOf(codigoComponenteTB.getText()));
			componente.setCodigoSubcomponente(0);
			// nombre del componente
			componente.setNombre(nombreComponenteTB.getText().toUpperCase());
			
			// se setea el id de la lista de materiales del equipo que contiene al componente
			componente.setIdListaMaterialesEquipoContenedor(equipoSeleccionado.getIdListaDeMateriales());		
		}
		
		// si se ha especificado un subcomponente
		else {
			
			componente.setCodigoComponente(Integer.valueOf(codigoComponenteCombo.getItemText(codigoComponenteCombo.getSelectedIndex())));
			componente.setCodigoSubcomponente(Integer.valueOf(codigoSubcomponenteTB.getText()));
			// nombre del subcomponente
			componente.setNombre(nombreSubcomponenteTB.getText().toUpperCase());
			
			// se busca el id de la lista de materiales del componente que contiene al subcomponente
			int componenteSeleccionado = Integer.valueOf(codigoComponenteCombo.getItemText(codigoComponenteCombo.getSelectedIndex()));
			
			for(ComponentePatronDTO c: listaComponentesPatron) {
				
				// si se trata del componente seleccionado
				if ((c.getCodigoComponente() == componenteSeleccionado) && (c.getCodigoSubcomponente() == 0)) {
					// se setea el id de la lista de materiales del componente que contiene al subcomponente
					componente.setIdListaMaterialesEquipoContenedor(c.getIdListaMateriales());
				}
			}
		}
		
		componente.setPlano(0);
		componente.setNroVersion("M0");
		componente.setDescripcionTecnica(descripcionTecnicaDetallesTA.getText());
		
		// si no es la cadena vacía
		if (!puntoPedidoTB.getText().equals("")) {
			componente.setPuntoPedido(Integer.valueOf(puntoPedidoTB.getText()));
		}
		
		// si no es la cadena vacía
		if (!loteTB.getText().equals("")) {
			componente.setLote(Integer.valueOf(loteTB.getText()));
		}
		
		componente.setActivo(true);
		componente.setCantidadDisponible(0);
		
		// se intenta hacer el registro del componente patrón
		ingenieriaService.registrarComponentePatron(componente, new AsyncCallback<ComponentePatronDTO>() {

			@Override
			public void onSuccess(ComponentePatronDTO componenteCreado) {
				
				if (componenteCreado != null) {
										
					String codigoComponente = Validaciones.rellenarCodigoComponentePatron(componenteCreado);
					
					// si se trata de un componente
					if (componenteCreado.getCodigoSubcomponente() == 0) {
					
						Window.alert("El componente patrón ha sido creado de manera exitosa.\nCódigo componente patrón: " + codigoComponente);
						salir();
					}
					
					// si se trata de un subcomponente
					else {
							
						Window.alert("El subcomponente patrón ha sido creado de manera exitosa.\nCódigo subcomponente patrón: " + codigoComponente);
						salir();
					}
				}
				
				else {
					
					// si se trata de un componente
					if (tipoCombo.getItemText(tipoCombo.getSelectedIndex()).equals("COMPONENTE")) {
					
						Window.alert("No se ha podido crear el componente patrón especificado.");
						crearComponenteBtn.setEnabled(true);
					}
					
					// si se trata de un subcomponente
					else {
							
						Window.alert("No se ha podido crear el subcomponente patrón especificado.");
						crearComponenteBtn.setEnabled(true);
					}
				}
			}

			@Override
			public void onFailure(Throwable caught) {
				Window.alert("ERROR EN EL SERVICIO");
				crearComponenteBtn.setEnabled(true);
			}
		});
	}
	
	/**
	 * Método que valida los datos ingresados por el usuario y devuelve una lista con los errores encontrados.
	 * @return lista de errores.
	 */
	private List<String> validarDatos() {
		
		Validaciones validar = new Validaciones();
		List<String> listaErrores = new LinkedList<String>();
		
		// se valida que se haya seleccionado el equipo de pertenencia
		if (!tipoCombo.isEnabled()) {
			listaErrores.add("- Se debe seleccionar el equipo al que pertenecerá el nuevo componente o subcomponente.");
		}
		
		else {
			
			// se verifica que el lote sea un número entero positivo, cero, o vacío.
			if (!loteTB.getText().equals("")) {
				
				try {				
					int lote = Integer.parseInt(loteTB.getText());
					
					// si el lote es menor a cero.
					if (lote < 0) {
						throw new Exception();
					}
				}
				
				catch (Exception e) {
					listaErrores.add("- El lote sólo puede ser un número entero positivo, cero, o bien quedar vacío.");			
				}
			}
			
			// se verifica que el punto de pedido sea un número entero positivo, cero, o vacío.
			if (!puntoPedidoTB.getText().equals("")) {
				
				try {
					int puntoPedido = Integer.parseInt(puntoPedidoTB.getText());
					
					if (puntoPedido < 0) {
						throw new Exception();
					}
				}
				
				catch (Exception e) {
					listaErrores.add("- El punto de pedido sólo puede ser un número entero positivo, cero, o bien quedar vacío.");
				}
			}
			
			// validaciones si se seleccionó componente
			if (tipoCombo.getItemText(tipoCombo.getSelectedIndex()).equals("COMPONENTE")) {
				
				// se verifica que el nombre de componente no sea vacío.
				if (validar.textBoxVacio(nombreComponenteTB.getText())) {
					listaErrores.add("- El nombre del componente no puede ser vacío.");
				}
				
				// se verifica que el nombre del componente no exista ya para el equipo patrón especificado.
				for (ComponentePatronDTO c: listaComponentesPatron) {
					
					// si el componente de la lista es un componente, y...
					if (c.getCodigoSubcomponente() == 0 && c.getNombre().equals(nombreComponenteTB.getText().toUpperCase())) {
						listaErrores.add("- El nombre del componente patrón ya existe para el equipo especificado.");
					}
				}				
			}
			
			// validaciones si se seleccionó subcomponente
			else {
				
				// se verifica que el nombre de subcomponente no sea vacío.
				if (validar.textBoxVacio(nombreSubcomponenteTB.getText())) {
					listaErrores.add("- El nombre del subcomponente no puede ser vacío.");
				}
				
				// se verifica que el nombre del subcomponente no exista ya para el equipo patrón y el componente especificado.
				for (ComponentePatronDTO c: listaComponentesPatron) {
					
					// si el componente de la lista es un subcomponente, y...
					if (c.getCodigoSubcomponente() != 0 && c.getNombre().equals(nombreSubcomponenteTB.getText().toUpperCase())) {
						listaErrores.add("- El nombre del subcomponente patrón ya existe para el equipo y componente especificados.");
					}
				}
			}			
		}

		return listaErrores;
	}

	public void salir() {
		padre.remove(Validaciones.numeroElemento(padre, tituloTab));
	}
}
